package com.gxar.quick.ar.server.base.async.user.listener;

import cn.hutool.core.util.StrUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.gxar.common.entity.excel.EasyExcelValidHelper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 用户兑换品导入解析器
 *
 * @param <T>
 * @author linsy
 */
@Slf4j
@Data
@EqualsAndHashCode(callSuper = true)
public class UserExchangeItemImportListener<T> extends AnalysisEventListener<T> {
    /**
     * 成功结果集
     */
    private List<T> successList = new ArrayList<>();

    /**
     * 失败信息字符串
     */
    private StringBuilder totalErrorMessage = new StringBuilder();

    /**
     * 失败计数
     */
    private Integer failedCount = 0;

    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        try {
            boolean exist = false;
            String[] fieldName = getFieldName(t);
            for (String string : fieldName) {
                Object fieldValue = getFieldValue(t, string);
                if (fieldValue instanceof String) {
                    if (StringUtils.isNotBlank((String) fieldValue)) {
                        exist = true;
                    }
                }
                if (!Objects.isNull(fieldValue)) {
                    exist = true;
                }
            }
            if (!exist) {
                // 去除空行
                return;
            }
            // 校验
            String errorMessage = EasyExcelValidHelper.validateEntity(t);
            // 校验失败
            if (StrUtil.isNotBlank(errorMessage)) {
                // 行数
                Integer rowIndex = analysisContext.readRowHolder().getRowIndex() + 1;
                totalErrorMessage.append("第").append(rowIndex).append("行的").append(errorMessage).append("\n");
                failedCount = failedCount + 1;
            } else {
                successList.add(t);
            }
        } catch (Exception e) {
            log.error("校验字段出现异常：" + e.getMessage(), e);
        }
    }

    /**
     * 获取属性名数组
     *
     * @param o 对象
     * @return 属性名数组
     */
    public String[] getFieldName(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        String[] fieldNames = new String[fields.length];
        for (int i = 0; i < fields.length; i++) {
            if (fields[i].isAnnotationPresent(ExcelProperty.class)) {
                fieldNames[i] = fields[i].getName();
            }
        }
        return fieldNames;
    }

    /**
     * 通过属性名获取属性值 忽略大小写
     *
     * @param o    对象
     * @param name 字段名
     * @return 字段值
     */
    public Object getFieldValue(Object o, String name) {
        if (Objects.isNull(name)) {
            return null;
        }
        try {
            Field[] fields = o.getClass().getDeclaredFields();
            Object object = null;
            for (Field field : fields) {
                // 可以获取到私有属性
                field.setAccessible(true);
                if (field.getName().toUpperCase().equals(name.toUpperCase())) {
                    object = field.get(o);
                    break;
                }
            }
            return object;
        } catch (Exception e) {
            log.warn("获取值异常,field={}", o, e);
            return false;
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}
